﻿using Core.DTO.System.SysPerson;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace Core.Common.Jwt
{
    public class JwtHelper
    {
        private IConfiguration Configuration { get; set; }

        public JwtHelper(IConfiguration configuration)
        {
            this.Configuration = configuration;

        }
        /// <summary>
        /// 颁发JWT字符串
        /// </summary>
        /// <param name="tokenModel"></param>
        /// <returns></returns>
        public string GetToken(TokenDTO tokenModel)
        {
            //issuer代表颁发Token的Web应用程序，
            //audience是Token的受理者
            // secret 是密钥
            string iss = Configuration["JwtSetting:Issuer"];
            string aud = Configuration["JwtSetting:Audience"];
            string secret = Configuration["JwtSetting:Secret"];

            // 定义声明  
            var claims = new List<Claim>
            {
                new Claim(JwtRegisteredClaimNames.Jti, tokenModel.Id.ToString()),
                new Claim(JwtRegisteredClaimNames.Iss,iss),
                new Claim(JwtRegisteredClaimNames.Aud,aud),
                new Claim("Name",tokenModel.Name),
                new Claim("RoleIds",tokenModel.Role),  // 角色Id
                new Claim("OrgId",tokenModel.OrgId.ToString())
                

                //new Claim(ClaimTypes.Role,tokenModel.Role),//为了解决一个用户多个角色(比如：Admin,System)，用下边的方法
            };

            // 可以将一个用户的多个角色全部赋予；
            //claims.AddRange(tokenModel.Role.Split(',').Select(s => new Claim(ClaimTypes.Role, s)));


            //秘钥 (SymmetricSecurityKey 对安全性的要求，密钥的长度太短会报出异常)
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            var jwt = new JwtSecurityToken(
                issuer: iss,
                claims: claims,
                expires: DateTime.Now.AddHours(1),
                signingCredentials: creds);

            var jwtHandler = new JwtSecurityTokenHandler();
            var encodedJwt = jwtHandler.WriteToken(jwt);

            return encodedJwt;
        }

        /// <summary>
        /// 解析
        /// </summary>
        /// <param name="jwtStr"></param>
        /// <returns></returns>
        public static TokenDTO GetTokenModel(string jwtStr)
        {

            var jwtHandler = new JwtSecurityTokenHandler();

            TokenDTO tokenModelJwt = null;

            // token校验
            if (!string.IsNullOrEmpty(jwtStr) && jwtHandler.CanReadToken(jwtStr))
            {
                JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(jwtStr);

                //object role;
                //jwtToken.Payload.TryGetValue(ClaimTypes.Role, out role);
                tokenModelJwt = new TokenDTO();
                tokenModelJwt.Id = Convert.ToInt32(jwtToken.Id);
                tokenModelJwt.Name = jwtToken.Payload.GetValueOrDefault("Name").ToString();
                tokenModelJwt.Role = jwtToken.Payload.GetValueOrDefault("RoleIds").ToString();
                tokenModelJwt.OrgId = Convert.ToInt32(jwtToken.Payload.GetValueOrDefault("OrgId"));
            }
            return tokenModelJwt;
        }
    }

}
